/**
 * 资源预加载器 (演示端精简版)
 * 在项目加载阶段预加载所有材质和纹理资源
 */

import * as THREE from '/lib/three/build/three.module.js';

class ResourcePreloader {
    constructor() {
        // 纹理缓存
        this.textureCache = new Map();
        
        // 加载状态
        this.isLoading = false;
        this.loadedCount = 0;
        this.totalCount = 0;
        
        // 纹理加载器
        this.textureLoader = new THREE.TextureLoader();
    }
    
    /**
     * 预加载项目资源（演示端版本）
     * @param {Object} config - 项目配置
     * @param {Object} projectData - 项目数据
     * @param {Function} onProgress - 进度回调
     */
    async preloadProjectResources(config, projectData, onProgress = null) {
        console.log('🔄 [资源预加载] 开始预加载项目资源...');
        
        this.isLoading = true;
        this.loadedCount = 0;
        this.totalCount = 0;
        
        const startTime = performance.now();
        
        try {
            // 根据模式获取基础URL
            const baseUrl = this.getBaseUrl(config);
            
            // 1. 加载材质配置
            console.log('📦 [资源预加载] 加载材质配置...');
            const materials = await this.loadMaterialConfigs(config, projectData, baseUrl);
            console.log(`✓ [资源预加载] 找到 ${materials.length} 个材质`);
            
            // 2. 提取纹理引用
            console.log('🔍 [资源预加载] 提取纹理引用...');
            const textureRefs = this.extractTextureReferences(materials);
            console.log(`✓ [资源预加载] 找到 ${textureRefs.size} 个唯一纹理引用`);
            
            // 3. 加载纹理列表
            console.log('📋 [资源预加载] 加载纹理列表...');
            const textureList = await this.loadTextureList(config, projectData, baseUrl);
            console.log(`✓ [资源预加载] 纹理库中有 ${textureList.length} 个纹理`);
            
            // 4. 批量预加载纹理
            console.log('📷 [资源预加载] 预加载纹理...');
            this.totalCount = textureRefs.size;
            
            const loadPromises = [];
            for (const textureRef of textureRefs) {
                const promise = this.preloadTexture(config, projectData, textureRef, textureList, baseUrl, onProgress);
                loadPromises.push(promise);
            }
            
            await Promise.all(loadPromises);
            
            const elapsedTime = ((performance.now() - startTime) / 1000).toFixed(2);
            console.log(`✅ [资源预加载] 预加载完成！`);
            console.log(`   - 材质数: ${materials.length}`);
            console.log(`   - 纹理数: ${this.textureCache.size}`);
            console.log(`   - 耗时: ${elapsedTime}秒`);
            
            return {
                success: true,
                materialsCount: materials.length,
                texturesCount: this.textureCache.size,
                elapsedTime: parseFloat(elapsedTime)
            };
            
        } catch (error) {
            console.error('❌ [资源预加载] 预加载失败:', error);
            return {
                success: false,
                error: error.message
            };
        } finally {
            this.isLoading = false;
        }
    }
    
    /**
     * 获取基础URL
     */
    getBaseUrl(config) {
        if (config.mode === 'offline') {
            return '';  // 离线模式使用相对路径
        } else if (config.mode === 'online') {
            return config.online.backendUrl;
        }
        return '';
    }
    
    /**
     * 加载材质配置
     */
    async loadMaterialConfigs(config, projectData, baseUrl) {
        try {
            let url;
            if (config.mode === 'offline') {
                // 离线模式：从本地路径加载
                const projectFolder = config.offline.projectFolder;
                url = `/project/${projectFolder}/materials/`;
                
                // 离线模式下需要遍历加载所有材质文件
                // 这里简化处理：尝试从 project.json 获取材质列表
                if (projectData.materials && projectData.materials.length > 0) {
                    const materials = [];
                    for (const matRef of projectData.materials) {
                        try {
                            const matUrl = `/project/${projectFolder}/materials/${matRef.id}.json`;
                            const response = await fetch(matUrl);
                            if (response.ok) {
                                const matData = await response.json();
                                materials.push(matData);
                            }
                        } catch (error) {
                            console.warn(`⚠️ 无法加载材质: ${matRef.id}`, error);
                        }
                    }
                    return materials;
                }
                return [];
            } else {
                // 在线模式：从 API 加载
                url = `${baseUrl}/api/projects/${projectData.id}/materials`;
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(`加载材质配置失败: ${response.status}`);
                }
                const result = await response.json();
                return result.data || [];
            }
        } catch (error) {
            console.error('❌ [资源预加载] 加载材质配置失败:', error);
            return [];
        }
    }
    
    /**
     * 提取纹理引用
     */
    extractTextureReferences(materials) {
        const textureRefs = new Set();
        const textureProperties = [
            'map', 'normalMap', 'roughnessMap', 'metalnessMap',
            'aoMap', 'emissiveMap', 'bumpMap', 'displacementMap', 'alphaMap'
        ];
        
        materials.forEach(material => {
            textureProperties.forEach(prop => {
                if (material[prop]) {
                    textureRefs.add(material[prop]);
                }
            });
        });
        
        return textureRefs;
    }
    
    /**
     * 加载纹理列表
     */
    async loadTextureList(config, projectData, baseUrl) {
        try {
            let url;
            if (config.mode === 'offline') {
                // 离线模式：从本地路径加载
                const projectFolder = config.offline.projectFolder;
                url = `/project/${projectFolder}/textures/`;
                
                // 离线模式下需要手动构建纹理列表
                // 简化处理：从 projectData 获取
                if (projectData.textures && projectData.textures.length > 0) {
                    return projectData.textures;
                }
                return [];
            } else {
                // 在线模式：从 API 加载
                url = `${baseUrl}/api/projects/${projectData.id}/textures`;
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(`加载纹理列表失败: ${response.status}`);
                }
                const result = await response.json();
                return result.data || [];
            }
        } catch (error) {
            console.error('❌ [资源预加载] 加载纹理列表失败:', error);
            return [];
        }
    }
    
    /**
     * 预加载单个纹理
     */
    async preloadTexture(config, projectData, textureRef, textureList, baseUrl, onProgress) {
        try {
            // 查找纹理信息
            const textureInfo = textureList.find(t => 
                t.displayName === textureRef || 
                t.name === textureRef ||
                t.id === textureRef
            );
            
            if (!textureInfo) {
                console.warn(`⚠️ [资源预加载] 未找到纹理: ${textureRef}`);
                this.loadedCount++;
                if (onProgress) onProgress(this.loadedCount, this.totalCount);
                return null;
            }
            
            // 构建纹理URL
            let textureUrl;
            if (config.mode === 'offline') {
                const projectFolder = config.offline.projectFolder;
                textureUrl = `/project/${projectFolder}/textures/${textureInfo.filename || textureInfo.id}`;
            } else {
                textureUrl = `${baseUrl}/api/projects/${projectData.id}/textures/${textureInfo.id}/file`;
            }
            
            // 检查缓存
            if (this.textureCache.has(textureUrl)) {
                console.log(`✓ [资源预加载] 纹理已缓存: ${textureRef}`);
                this.loadedCount++;
                if (onProgress) onProgress(this.loadedCount, this.totalCount);
                return this.textureCache.get(textureUrl);
            }
            
            // 加载纹理
            return new Promise((resolve) => {
                this.textureLoader.load(
                    textureUrl,
                    (texture) => {
                        texture.colorSpace = THREE.SRGBColorSpace;
                        texture.wrapS = THREE.RepeatWrapping;
                        texture.wrapT = THREE.RepeatWrapping;
                        
                        // 🔧 修复模糊问题：设置高质量纹理过滤
                        texture.generateMipmaps = true;
                        texture.minFilter = THREE.LinearMipmapLinearFilter;
                        texture.magFilter = THREE.LinearFilter;
                        // 查看器中没有全局 manager，尝试从 window 获取
                        const renderer = window.sceneViewer?.renderer;
                        const maxAnisotropy = renderer ? renderer.capabilities.getMaxAnisotropy() : 16;
                        texture.anisotropy = maxAnisotropy;
                        texture.needsUpdate = true;
                        
                        this.textureCache.set(textureUrl, texture);
                        
                        this.loadedCount++;
                        if (onProgress) {
                            onProgress(this.loadedCount, this.totalCount);
                        }
                        
                        // console.log(`✓ [资源预加载] 纹理加载完成: ${textureRef} (${this.loadedCount}/${this.totalCount})`);
                        resolve(texture);
                    },
                    undefined,
                    (error) => {
                        console.warn(`⚠️ [资源预加载] 纹理加载失败: ${textureRef}`, error);
                        this.loadedCount++;
                        if (onProgress) onProgress(this.loadedCount, this.totalCount);
                        resolve(null);
                    }
                );
            });
            
        } catch (error) {
            console.error(`❌ [资源预加载] 预加载纹理异常: ${textureRef}`, error);
            this.loadedCount++;
            if (onProgress) onProgress(this.loadedCount, this.totalCount);
            return null;
        }
    }
    
    /**
     * 获取已缓存的纹理
     */
    getCachedTexture(textureUrl) {
        return this.textureCache.get(textureUrl) || null;
    }
    
    /**
     * 清除缓存
     */
    clearCache() {
        console.log('🧹 [资源预加载] 清除缓存...');
        this.textureCache.forEach(texture => {
            if (texture && texture.dispose) {
                texture.dispose();
            }
        });
        this.textureCache.clear();
        this.loadedCount = 0;
        this.totalCount = 0;
        console.log('✓ [资源预加载] 缓存已清除');
    }
}

export default ResourcePreloader;

